#include "ConfigurationFrame.h"

#include <sstream>

ConfigurationFrame::ConfigurationFrame() :
							configuracionFrame("Configuracion"),
							generalFrame("General"),
							probabilidadesFrame("Probabilidades"),
							celdaFrame("Celda"),
							columnaFrame("Columna"),
							nombreNivelLabel("Nombre nivel"),
							imagenFondoLabel("Imagen de fondo"),
							puntajeRequeridoLabel("Puntaje requerido"),
							maximoJugadoresLabel("Máx. jugadores"),
							cantidadFilasLabel("Cantidad filas"),
							cantidadColumnasLabel("Cantidad columnas"),
							sonidoMovimientoLabel("Sonido movimiento"),
							sonidoCombinacionLabel("Sonido combinación"),
							celdaRedLabel("R"),
							celdaYellowLabel("Y"),
							celdaGreenLabel("G"),
							celdaBlueLabel("B"),
							celdaVioletLabel("V"),
							columnaRedLabel("R"),
							columnaYellowLabel("Y"),
							columnaGreenLabel("G"),
							columnaBlueLabel("B"),
							columnaVioletLabel("V"),
							celdaButtonLabel("Button"),
							celdaMiniBarLabel("Mini Bar"),
							celdaGoldenStarLabel("Golden Star"),
							columnaButtonLabel("Button"),
							columnaMiniBarLabel("Mini Bar"),
							columnaGoldenStarLabel("Golden Star") {
	nombreNivelEntry.set_text("Test");

	/* Creo los adjustments para limitar los valores de las probabilidades 
	 * y setear los valores por defecto */
	celdaBlueButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaGreenButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaRedButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaVioletButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaYellowButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaBlueButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaGreenButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaRedButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaVioletButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaYellowButtonSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));

	celdaBlueMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaGreenMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaRedMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaVioletMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	celdaYellowMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaBlueMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaGreenMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaRedMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaVioletMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));
	columnaYellowMiniBarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.09, 0, 1, 0.01));

    celdaGoldenStarSpinButton.set_adjustment(
		Gtk::Adjustment::create(0.10, 0, 1, 0.01));
    columnaGoldenStarSpinButton.set_adjustment
    (Gtk::Adjustment::create(0.10, 0, 1, 0.01));

	/* Seteo la cantidad de dígitos visibles para los campos de probabilidad */
    celdaRedButtonSpinButton.set_digits(2);
    celdaYellowButtonSpinButton.set_digits(2);
    celdaGreenButtonSpinButton.set_digits(2);
    celdaBlueButtonSpinButton.set_digits(2);
    celdaVioletButtonSpinButton.set_digits(2);
    columnaRedButtonSpinButton.set_digits(2);
    columnaYellowButtonSpinButton.set_digits(2);
    columnaGreenButtonSpinButton.set_digits(2);
    columnaBlueButtonSpinButton.set_digits(2);
    columnaVioletButtonSpinButton.set_digits(2);
    celdaRedMiniBarSpinButton.set_digits(2);
    celdaYellowMiniBarSpinButton.set_digits(2);
    celdaGreenMiniBarSpinButton.set_digits(2);
    celdaBlueMiniBarSpinButton.set_digits(2);
    celdaVioletMiniBarSpinButton.set_digits(2);
    columnaRedMiniBarSpinButton.set_digits(2);
    columnaYellowMiniBarSpinButton.set_digits(2);
    columnaGreenMiniBarSpinButton.set_digits(2);
    columnaBlueMiniBarSpinButton.set_digits(2);
    columnaVioletMiniBarSpinButton.set_digits(2);
    celdaGoldenStarSpinButton.set_digits(2);
    columnaGoldenStarSpinButton.set_digits(2);

	/* Seteo los adjustments para otros campos numéricos limitados */
    puntajeRequeridoSpinButton.set_adjustment(
		Gtk::Adjustment::create(10000, 10000, 1000000));
    maximoJugadoresSpinButton.set_adjustment(
		Gtk::Adjustment::create(2, 2, 8));
    cantidadFilasSpinButton.set_adjustment(
		Gtk::Adjustment::create(8, 6, 10));
    cantidadColumnasSpinButton.set_adjustment(
		Gtk::Adjustment::create(8, 6, 10));

	/* Agrego todos los widgets a la ventana */
    celdaTable.attach(celdaRedLabel, 1, 2, 0, 1);
    celdaTable.attach(celdaYellowLabel, 2, 3, 0, 1);
    celdaTable.attach(celdaGreenLabel, 3, 4, 0, 1);
    celdaTable.attach(celdaBlueLabel, 4, 5, 0, 1);
    celdaTable.attach(celdaVioletLabel, 5, 6, 0, 1);

    celdaTable.attach(celdaButtonLabel, 0, 1, 1, 2);

    celdaTable.attach(celdaRedButtonSpinButton, 1, 2, 1, 2);
    celdaTable.attach(celdaYellowButtonSpinButton, 2, 3, 1, 2);
    celdaTable.attach(celdaGreenButtonSpinButton, 3, 4, 1, 2);
    celdaTable.attach(celdaBlueButtonSpinButton, 4, 5, 1, 2);
    celdaTable.attach(celdaVioletButtonSpinButton, 5, 6, 1, 2);

    celdaTable.attach(celdaMiniBarLabel, 0, 1, 2, 3);

    celdaTable.attach(celdaRedMiniBarSpinButton, 1, 2, 2, 3);
    celdaTable.attach(celdaYellowMiniBarSpinButton, 2, 3, 2, 3);
    celdaTable.attach(celdaGreenMiniBarSpinButton, 3, 4, 2, 3);
    celdaTable.attach(celdaBlueMiniBarSpinButton, 4, 5, 2, 3);
    celdaTable.attach(celdaVioletMiniBarSpinButton, 5, 6, 2, 3);

    celdaTable.attach(celdaSeparator, 0, 6, 3, 4);

    celdaTable.attach(celdaGoldenStarLabel, 0, 1, 4, 5);
    celdaTable.attach(celdaGoldenStarSpinButton, 1, 2, 4, 5);

    columnaTable.attach(columnaRedLabel, 1, 2, 0, 1);
    columnaTable.attach(columnaYellowLabel, 2, 3, 0, 1);
    columnaTable.attach(columnaGreenLabel, 3, 4, 0, 1);
    columnaTable.attach(columnaBlueLabel, 4, 5, 0, 1);
    columnaTable.attach(columnaVioletLabel, 5, 6, 0, 1);

    columnaTable.attach(columnaButtonLabel, 0, 1, 1, 2);

    columnaTable.attach(columnaRedButtonSpinButton, 1, 2, 1, 2);
    columnaTable.attach(columnaYellowButtonSpinButton, 2, 3, 1, 2);
    columnaTable.attach(columnaGreenButtonSpinButton, 3, 4, 1, 2);
    columnaTable.attach(columnaBlueButtonSpinButton, 4, 5, 1, 2);
    columnaTable.attach(columnaVioletButtonSpinButton, 5, 6, 1, 2);

    columnaTable.attach(columnaMiniBarLabel, 0, 1, 2, 3);

    columnaTable.attach(columnaRedMiniBarSpinButton, 1, 2, 2, 3);
    columnaTable.attach(columnaYellowMiniBarSpinButton, 2, 3, 2, 3);
    columnaTable.attach(columnaGreenMiniBarSpinButton, 3, 4, 2, 3);
    columnaTable.attach(columnaBlueMiniBarSpinButton, 4, 5, 2, 3);
    columnaTable.attach(columnaVioletMiniBarSpinButton, 5, 6, 2, 3);

    columnaTable.attach(columnaSeparator, 0, 6, 3, 4);

    columnaTable.attach(columnaGoldenStarLabel, 0, 1, 4, 5);
    columnaTable.attach(columnaGoldenStarSpinButton, 1, 2, 4, 5);

    celdaFrame.add(celdaTable);
    columnaFrame.add(columnaTable);

    probabilidadesHBox.add(celdaFrame);
    probabilidadesHBox.add(columnaFrame);

    generalTable.attach(nombreNivelLabel, 0, 1, 0, 1);
    generalTable.attach(nombreNivelEntry, 1, 2, 0, 1);
    generalTable.attach(imagenFondoLabel, 0, 1, 1, 2);
    generalTable.attach(imagenFondoFileChooser, 1, 2, 1, 2);
    generalTable.attach(puntajeRequeridoLabel, 0, 1, 2, 3);
    generalTable.attach(puntajeRequeridoSpinButton, 1, 2, 2, 3);
    generalTable.attach(maximoJugadoresLabel, 0, 1, 3, 4);
    generalTable.attach(maximoJugadoresSpinButton, 1, 2, 3, 4);
    generalTable.attach(cantidadFilasLabel, 0, 1, 4, 5);
    generalTable.attach(cantidadFilasSpinButton, 1, 2, 4, 5);
    generalTable.attach(cantidadColumnasLabel, 0, 1, 5, 6);
    generalTable.attach(cantidadColumnasSpinButton, 1, 2, 5, 6);
	generalTable.attach(sonidoMovimientoLabel, 0, 1, 6, 7);
    generalTable.attach(sonidoMovimientoFileChooser, 1, 2, 6, 7);
	generalTable.attach(sonidoCombinacionLabel, 0, 1, 7, 8);
    generalTable.attach(sonidoCombinacionFileChooser, 1, 2, 7, 8);
	
    generalFrame.add(generalTable);
    probabilidadesFrame.add(probabilidadesHBox);

    configuracionHBox.add(generalFrame);
    configuracionHBox.add(probabilidadesFrame);

    configuracionFrame.add(configuracionHBox);

    mainVBox.add(configuracionFrame);

    add(mainVBox);
    show_all_children(true);
}

ConfigurationFrame::~ConfigurationFrame() {
}

GeneralConfiguration* ConfigurationFrame::obtenerConfiguracion() {
    GeneralConfiguration *gc = new GeneralConfiguration();

	std::string imagenFondo = imagenFondoFileChooser.get_filename();
	std::string sonidoMovimiento = sonidoMovimientoFileChooser.get_filename();
	std::string sonidoCombinacion = sonidoCombinacionFileChooser.get_filename();
	
	/* Me quedo con el nombre del archivo nomás */
	imagenFondo = 
		imagenFondo.substr(imagenFondo.find_last_of("/") + 1);
	sonidoMovimiento = 
		sonidoMovimiento.substr(sonidoMovimiento.find_last_of("/") + 1);
	sonidoCombinacion = 
		sonidoCombinacion.substr(sonidoCombinacion.find_last_of("/") + 1);
	
	/* Seteo los valores en la configuración */
    gc->setCeldaBlueButton(celdaBlueButtonSpinButton.get_value());
    gc->setCeldaBlueMiniBar(celdaBlueMiniBarSpinButton.get_value());
    gc->setCeldaGoldenStar(celdaGoldenStarSpinButton.get_value());
    gc->setCeldaGreenButton(celdaGreenButtonSpinButton.get_value());
    gc->setCeldaGreenMiniBar(celdaGreenMiniBarSpinButton.get_value());
    gc->setCeldaRedButton(celdaRedButtonSpinButton.get_value());
    gc->setCeldaRedMiniBar(celdaRedMiniBarSpinButton.get_value());
    gc->setCeldaVioletButton(celdaVioletButtonSpinButton.get_value());
    gc->setCeldaVioletMiniBar(celdaVioletMiniBarSpinButton.get_value());
    gc->setCeldaYellowButton(celdaYellowButtonSpinButton.get_value());
    gc->setCeldaYellowMiniBar(celdaYellowMiniBarSpinButton.get_value());
    gc->setColumnaBlueButton(columnaBlueButtonSpinButton.get_value());
    gc->setColumnaBlueMiniBar(columnaBlueMiniBarSpinButton.get_value());
    gc->setColumnaGoldenStar(columnaGoldenStarSpinButton.get_value());
    gc->setColumnaGreenButton(columnaGreenButtonSpinButton.get_value());
    gc->setColumnaGreenMiniBar(columnaGreenMiniBarSpinButton.get_value());
    gc->setColumnaRedButton(columnaRedButtonSpinButton.get_value());
    gc->setColumnaRedMiniBar(columnaRedMiniBarSpinButton.get_value());
    gc->setColumnaVioletButton(columnaVioletButtonSpinButton.get_value());
    gc->setColumnaVioletMiniBar(columnaVioletMiniBarSpinButton.get_value());
    gc->setColumnaYellowButton(columnaYellowButtonSpinButton.get_value());
    gc->setColumnaYellowMiniBar(columnaYellowMiniBarSpinButton.get_value());
    gc->setImagenFondo(imagenFondo);
    gc->setMaximoJugadores(maximoJugadoresSpinButton.get_value_as_int());
    gc->setNombreNivel(nombreNivelEntry.get_text());
    gc->setPuntajeRequerido(puntajeRequeridoSpinButton.get_value_as_int());
    gc->setCantidadFilas(cantidadFilasSpinButton.get_value_as_int());
    gc->setCantidadColumnas(cantidadColumnasSpinButton.get_value_as_int());
	gc->setSonidoMovimiento(sonidoMovimiento);
	gc->setSonidoCombinacion(sonidoCombinacion);

    return gc;
}

void ConfigurationFrame::setConfiguracion(GeneralConfiguration* gc) {
	celdaBlueButtonSpinButton.set_value(gc->getCeldaBlueButton());
	celdaGreenButtonSpinButton.set_value(gc->getCeldaGreenButton());
	celdaRedButtonSpinButton.set_value(gc->getCeldaRedButton());
	celdaVioletButtonSpinButton.set_value(gc->getCeldaVioletButton());
	celdaYellowButtonSpinButton.set_value(gc->getCeldaYellowButton());
	celdaBlueMiniBarSpinButton.set_value(gc->getCeldaBlueMiniBar());
	celdaGreenMiniBarSpinButton.set_value(gc->getCeldaGreenMiniBar());
	celdaRedMiniBarSpinButton.set_value(gc->getCeldaRedMiniBar());
	celdaVioletMiniBarSpinButton.set_value(gc->getCeldaVioletMiniBar());
	celdaYellowMiniBarSpinButton.set_value(gc->getCeldaYellowMiniBar());
	celdaGoldenStarSpinButton.set_value(gc->getCeldaGoldenStar());

    columnaBlueButtonSpinButton.set_value(gc->getColumnaBlueButton());
	columnaGreenButtonSpinButton.set_value(gc->getColumnaGreenButton());
	columnaRedButtonSpinButton.set_value(gc->getColumnaRedButton());
	columnaVioletButtonSpinButton.set_value(gc->getColumnaVioletButton());
	columnaYellowButtonSpinButton.set_value(gc->getColumnaYellowButton());
	columnaBlueMiniBarSpinButton.set_value(gc->getColumnaBlueMiniBar());
	columnaGreenMiniBarSpinButton.set_value(gc->getColumnaGreenMiniBar());
	columnaRedMiniBarSpinButton.set_value(gc->getColumnaRedMiniBar());
	columnaVioletMiniBarSpinButton.set_value(gc->getColumnaVioletMiniBar());
	columnaYellowMiniBarSpinButton.set_value(gc->getColumnaYellowMiniBar());
	columnaGoldenStarSpinButton.set_value(gc->getColumnaGoldenStar());

    imagenFondoFileChooser.set_filename(gc->getImagenFondo());
    maximoJugadoresSpinButton.set_value(gc->getMaximoJugadores());
    nombreNivelEntry.set_text(gc->getNombreNivel());
    puntajeRequeridoSpinButton.set_value(gc->getPuntajeRequerido());
    cantidadFilasSpinButton.set_value(gc->getCantidadFilas());
    cantidadColumnasSpinButton.set_value(gc->getCantidadColumnas());
	sonidoMovimientoFileChooser.set_filename(gc->getSonidoMovimiento());
	sonidoCombinacionFileChooser.set_filename(gc->getSonidoCombinacion());
}

bool ConfigurationFrame::validar(std::string &error) {
	std::stringstream ss;

	bool valido = true;

    double sumaProbabilidadesCelda = 0;
    double sumaProbabilidadesColumna = 0;

    /* Sumo las probabilidades para las celdas */
    sumaProbabilidadesCelda += celdaBlueButtonSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaBlueMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaGoldenStarSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaGreenButtonSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaGreenMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaRedButtonSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaRedMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaVioletButtonSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaVioletMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaYellowButtonSpinButton.get_value() * 100;
    sumaProbabilidadesCelda += celdaYellowMiniBarSpinButton.get_value() * 100;

    /* Sumo las probabilidades para las columnas */
    sumaProbabilidadesColumna += columnaBlueButtonSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaBlueMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaGoldenStarSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaGreenButtonSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaGreenMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaRedButtonSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaRedMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaVioletButtonSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaVioletMiniBarSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaYellowButtonSpinButton.get_value() * 100;
    sumaProbabilidadesColumna += columnaYellowMiniBarSpinButton.get_value() * 100;

    /* Las probabilidades deben cerrar a 1 */
    if (sumaProbabilidadesCelda != 100) {
		ss << "La suma de probabilidades por celda debe ser igual a 1.\n";
		ss << "La suma actual es: " << sumaProbabilidadesCelda / 100.0f << "\n";
        valido = false;
	}

    if (sumaProbabilidadesColumna != 100) {
        ss << "La suma de probabilidades por columna debe ser igual a 1.\n";
		ss << "La suma actual es: " << sumaProbabilidadesColumna / 100.0f << "\n";
        valido = false;
    }

    /* Si no hay nombre para el nivel... */
    if (nombreNivelEntry.get_text().length() < 4) {
		ss << "El nombre del nivel debe tener por lo menos 4 caracteres";
        valido = false;
    }

    error = ss.str();
    return valido;
}
